package org.uc3m.pfc.configuration;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.uc3m.pfc.data.Action;
import org.uc3m.pfc.data.Device;
import org.uc3m.pfc.data.House;
import org.uc3m.pfc.data.Zone;

import android.content.Context;
import android.content.res.AssetManager;

/**
 * 
 * @author esteban
 *
 */
public final class ConfigurationReader {
	
	// Class fields *******************************************************

	/** Path to json configuration file. */
	private static final String PATH = "settings.json";
	
	/** JSON Node names settings. */
	private static final String TAG_SETTINGS = "settings";
	/** JSON Node names url. */
	private static final String TAG_URL = "url";
	/** JSON Node names house. */
	private static final String TAG_HOUSE = "house";
	/** JSON Node names id. */
	private static final String TAG_ID = "id";
	/** JSON Node names name. */
	private static final String TAG_NAME = "name";
	/** JSON Node names zones. */
	private static final String TAG_ZONES = "zones";
	/** JSON Node names device. */
	private static final String TAG_DEVICES = "devices";
	/** JSON Node names actions. */
	private static final String TAG_ACTIONS = "actions";

	/** Static instance. */
	private static ConfigurationReader reader;
	
	
    // Constructor *******************************************************
	
	/**
	 * Private default constructor.
	 */
	private ConfigurationReader() {
		
	}
	
	/**
	 * Get the reader.
	 * 
	 * @return instance
	 */
	public static ConfigurationReader getReader() {
		
		if (reader == null) {
			reader = new ConfigurationReader();
		}
		
		return reader;
	}
	
	
    // Public methods ****************************************************
	
	/**
	 * Load the configuration file into an house object.
	 * 
	 * @param context for getting json file
	 * @return data object
	 */
	public House loadConfiguration(final Context context) {
		
		House house = null;
		
		String jsonData = loadJSONFromAsset(context);
		
		try {
			JSONObject json = new JSONObject(jsonData);
			JSONObject settings = json.getJSONObject(TAG_SETTINGS);
			
			String url = settings.getString(TAG_URL);
			
			JSONObject houseJSON = settings.getJSONObject(TAG_HOUSE);
			int idHouse = houseJSON.getInt(TAG_ID);
			String nameHouse = houseJSON.getString(TAG_NAME);
			String urlHouse = houseJSON.getString(TAG_URL);
			
			JSONArray zonesJSON = houseJSON.getJSONArray(TAG_ZONES);
			List<Zone> zones = new ArrayList<Zone>();
			
			// looping through all zones
		    for (int i = 0; i < zonesJSON.length(); i++) {
		    	
		        JSONObject zoneJSON = zonesJSON.getJSONObject(i);
				int idZone = zoneJSON.getInt(TAG_ID);
				String nameZone = zoneJSON.getString(TAG_NAME);
				String urlZone = zoneJSON.getString(TAG_URL);

				JSONArray devicesJSON = zoneJSON.getJSONArray(TAG_DEVICES);
				List<Device> devices = new ArrayList<Device>();
				
				// looping through all devices
			    for (int j = 0; j < devicesJSON.length(); j++) {
			    	
			        JSONObject deviceJSON = devicesJSON.getJSONObject(j);
					int idDevice = deviceJSON.getInt(TAG_ID);
					String nameDevice = deviceJSON.getString(TAG_NAME);
					String urlDevice = deviceJSON.getString(TAG_URL);
		
					JSONArray actionsJSON = deviceJSON.getJSONArray(
							TAG_ACTIONS);
					List<Action> actions = new ArrayList<Action>();
					
					// looping through all actions
				    for (int k = 0; k < actionsJSON.length(); k++) {
				    	
				        JSONObject actionJSON = actionsJSON.getJSONObject(k);
						int idAction = actionJSON.getInt(TAG_ID);
						String nameAction = actionJSON.getString(TAG_NAME);
						String urlAction = actionJSON.getString(TAG_URL);
						
						Action action = new Action(idAction, nameAction, 
								urlAction);
						actions.add(action);
					}
				    
					Device device = new Device(idDevice, nameDevice, urlDevice, 
							actions);
					devices.add(device);				    
				}
			    
			    Zone zone = new Zone(idZone, nameZone, urlZone, devices);
			    zones.add(zone);
			}

			house = new House(idHouse, nameHouse, urlHouse, zones);
			
		} catch (JSONException e) {

			// TODO handle error
			e.printStackTrace();
			house = null;
		}
		
		return house;
	}

	
    // Private methods ****************************************************
	
	/**
	 * Load the configuration file from the context of activity.
	 * 
	 * @param context application context
	 * @return string with json contents
	 */
	private String loadJSONFromAsset(final Context context) {
        
		String json = null;
        
        try {
			AssetManager mngr = context.getAssets();
			InputStream is = mngr.open(PATH);

			int size = is.available();

			byte[] buffer = new byte[size];

			is.read(buffer);

			is.close();

			json = new String(buffer, "UTF-8");

        } catch (IOException ex) {
        	
        	// TODO handle error
            ex.printStackTrace();
            return null;
        }
        
        return json;

    }
	
	
}
